package com.example.socket.anno.impl;

import com.example.socket.anno.InSession;
import com.example.socket.core.*;
import com.example.socket.exception.IdentityParameterException;
import com.example.socket.exception.SessionParameterException;
import com.example.socket.parameter.Parameter;
import com.example.socket.parameter.ParameterKind;
import com.example.socket.parameter.ResultCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;

import java.net.SocketAddress;

/**
 * @author frank
 */
public class InSessionParameter implements Parameter {

    private static final Logger logger = LoggerFactory.getLogger(InSessionParameter.class);

    private InSession annotation;

    public static InSessionParameter valueOf(InSession annotation) {
        InSessionParameter result = new InSessionParameter();
        result.annotation = annotation;
        return result;
    }

    @Override
    public ParameterKind getKind() {
        return ParameterKind.IN_SESSION;
    }

    @Override
    public Object getValue(Request<?> request, Session session, ResultCallback<?> callback) {
        if (session == null) {
            return null;
        }

        String key = annotation.value();
        SessionContext context = session.getContext();
        if (context == null) {
            // 未初始化SESSION上下文
            return null;
        }
        Object value;
        if (key.equals(SessionKeys.IDENTITY)) {
            value = context.getIdentity();
        } else {
            value = context.get(key);
        }

        if (value != null) {
            return value;
        }

        if (key.equals(SessionKeys.IDENTITY)) {
            // 玩家未登录
            Command command = request.getCommand();
            SocketAddress address = session.getRemoteAddress();
            FormattingTuple message = MessageFormatter.format("指令[{}]要求的身份信息不存在, 连接[{}]", command, address);
            logger.warn(message.getMessage());
            throw new IdentityParameterException(message.getMessage());
        }

        if (annotation.required()) {
            Command command = request.getCommand();
            SocketAddress address = session.getRemoteAddress();
            FormattingTuple message = MessageFormatter.format("指令[{}]注释[{}]要求的SESSION参数不存在, 连接[{}]", new Object[]{
                    command, annotation, address});
            logger.warn(message.getMessage());
            throw new SessionParameterException(message.getMessage());
        } else {
            return null;
        }
    }

}
